package uw10.app;

import uw10.app.data.sources.RecentPrioritySource;
import uw10.app.data.sources.impl.RandomRecentPrioritySource;
import uw10.app.net.ClientServerManager;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class MainService extends Service implements RecentPriorityListener
{
	private final IBinder binder = new MainServiceBinder();
	
	private ClientServerManager csm;
	private MainServiceThread mst;
	private SharedPreferences settings;
	
	private String host;
	private int pingPort;
	private boolean active;
	private long period;
	private int threshold;

    public void onCreate() 
    {
    	Log.w("MainService", "onCreate");
    	
    	csm = new ClientServerManager();
    	
    	mst = new MainServiceThread(csm, 0, 0, this);
    	
    	settings = getSharedPreferences("uw10.app.MainService.settings", MODE_PRIVATE);
    	loadSettings();
  
    }
    
    private void loadSettings()
	{
    	setActive(settings.getBoolean("active", false));
    	setHost(settings.getString("host", "default"));
    	setPingPort(settings.getInt("pingPort", 0));
		setThreshold(settings.getInt("threshold", 0));
		setPeriod(settings.getLong("period", 10 * 60000));
	}
	
	private void storeSettings()
	{
		SharedPreferences.Editor edit = settings.edit();
		edit.putBoolean("active", active);
		edit.putString("host", host);
		edit.putInt("pingPort", pingPort);
		edit.putLong("period", period);
		edit.putInt("threshold", threshold);
		edit.commit();
	}

    public int onStartCommand(Intent intent, int flags, int startId)
    {
    	Log.w("MainService", "onStartCommand");
        return START_STICKY;
    }

    public void onDestroy()
    {
    	Log.w("MainService", "onDestroy");
    	
    	mst.stop();
    	
    	storeSettings();
    }

    public IBinder onBind(Intent intent)
    {
        return binder;
    }
    
    public class MainServiceBinder extends Binder
    {
        MainService getService()
        {
            return MainService.this;
        }
    }
    
    public int getPingPort()
    {
    	return pingPort;
    }
    
    public void setPingPort(int pingPort)
    {
    	this.pingPort = pingPort;
    	csm.setupPing(host, pingPort);
    }
    
    public boolean getActive()
    {
    	return active;
    }
    
    public String getHost()
    {
    	return host;
    }
    
    public long getPeriod()
    {
    	return period;
    }
    
    public int getThreshold()
    {
    	return threshold;
    }
    
    public void setActive(boolean active)
    {
    	this.active = active;
    	if (active)
    		mst.setPeriod(period);
    	else
    		mst.setPeriod(0);
    }
    
    public void setHost(String host)
    {
    	this.host = host;
    	csm.setupPing(host, pingPort);
    }
    
    public void setPeriod(long period)
    {
    	this.period = period;
    	if (active)
    		mst.setPeriod(period);
    }
    
    public void setThreshold(int threshold)
    {
    	this.threshold = threshold;
    	mst.setThreshold(threshold);
    }
    
	public void recentPriorityThresholdExceeded(int priority)
    {
		Log.w("MainService", "startActivity");
		
		startActivity(new Intent(this, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
	}
    
    private class MainServiceThread implements Runnable
    {
    	private volatile Thread thread;
    	
    	private RecentPrioritySource source;
    	private volatile long period;
		private volatile int threshold;
		
		RecentPriorityListener listener;
    	
    	public MainServiceThread(RecentPrioritySource source, long period, int threshold, RecentPriorityListener listener)
    	{
    		this.source = source;
    		this.threshold = threshold;
    		this.listener = listener;
    		
    		setPeriod(period);
    	}
    	
    	public synchronized void setPeriod(long period)
    	{
    		this.period = period;
    		if (period > 0)
    			start();
    		else
    			stop();
    	}
    	
    	public void setThreshold(int threshold)
    	{
    		this.threshold = threshold;
    	}
    	
		public void run()
		{
			while (Thread.currentThread() == thread)
			{
				int priority = source.getRecentPriority();
				if (priority >= threshold)
				{
					listener.recentPriorityThresholdExceeded(priority);
				}
				
				try
				{
					Thread.sleep(period);
				}
				catch (InterruptedException e) { }
			}
		}
		
		public synchronized void start()
		{
			if (thread == null)
			{
				thread = new Thread(this);
				thread.start();
			}
		}
		
		public synchronized void stop()
		{
			thread = null;
		}
    }
}

interface RecentPriorityListener
{
	void recentPriorityThresholdExceeded(int priority);
}
